package com.zdp.utils;

import io.minio.MinioClient;
import io.minio.PutObjectOptions;
import io.minio.messages.Bucket;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Objects;

/**
 * @author sesshomaru
 * @date 2021/3/3
 */
@Slf4j
@Service
public class MinioOperator {

    @Autowired
    private MinioClient minioClient;

    /**
     * 默认存储桶名称
     */
    @Value("${minio.bucketName}")
    private String defaultBucketName;

    /**
     * 下载
     * @param bucketName
     * @param objectName
     * @param fileName
     * @param dir
     */
    public void download(String bucketName, String objectName, String fileName, String dir){
        try {
            InputStream inputStream = minioClient.getObject(bucketName, objectName);
            if (Objects.isNull(inputStream) || inputStream.available() == 0) return;
            log.info("开始下载文件");
            File file = new File(dir);
            if (!file.exists()) {
                file.mkdirs();
            }
            FileOutputStream outputStream =  new FileOutputStream(new File(dir, fileName));
            int length;
            byte[] buffer = new byte[1024];
            while ((length = inputStream.read(buffer)) != -1) {
                outputStream.write(buffer, 0, length);
            }
            outputStream.close();
            inputStream.close();
        }catch (Exception e) {
            log.error(e.getMessage(), e);
        }
    }

    /**
     * 根据指定的objectName获取下载链接，需要bucket设置可下载的策略
     * @param bucketName
     * @param objectName
     * @return
     */
    public String getObjectUrl(String bucketName, String objectName){
        try {
            return minioClient.getObjectUrl(bucketName, objectName);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return "";
    }

    /**
     * 通过流上传内容到minio
     * @param bucketName 桶名
     * @param objectName 文件名 test.jpg
     * @return 访问地址
     */
    public String uploadToMinio(String bucketName, String objectName, InputStream in) {
        bucketBuild(bucketName);
        try {
            minioClient.putObject(bucketName, objectName, in, new PutObjectOptions(in.available(), -1));
            // objectUrl示例: http://39.106.77.123:9562/test/8341f05e-5801-4ae0-aeb0-ddb7ebedb16b.jpg
            String objectUrl = getObjectUrl(bucketName, objectName);
            for (int i = 0; i < 3; i++) {
                objectUrl = objectUrl.substring(objectUrl.indexOf("/") + 1);
            }
            // 截取后返回的示例: test/8341f05e-5801-4ae0-aeb0-ddb7ebedb16b.jpg
            return objectUrl;
        } catch (Exception e) {
            log.error(e.getMessage(), e);
        } finally {
            try {
                in.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        return "";
    }

    public void delete(String bucketName, String objectName){
        try {
            minioClient.removeObject(bucketName, objectName);
        } catch (Exception e) {
            log.error(e.getMessage(), e);
        }
    }

    /**
     * 获取minio所有的桶
     * @return
     */
    public List<Bucket> listBuckets(){
        try {
            List<Bucket> buckets = minioClient.listBuckets();
            for (Bucket bucket : buckets) {
                log.info("bucket 名称:{}   bucket 创建时间:{}", bucket.name(), bucket.creationDate());
            }
            return buckets;
        }catch (Exception e) {
            log.error(e.getMessage(), e);
        }
        return Collections.emptyList();
    }

    /**
     * 构建存储桶
     * @param bucketName
     */
    private void bucketBuild(String bucketName) {
        try {
            // 查询存储桶是否存在
            boolean found = minioClient.bucketExists(bucketName);
            if (!found) {
                // 创建存储桶
                minioClient.makeBucket(bucketName);
                //log.info("Bucket " + bucketName + " make success.");
            } else {
                //log.info("Bucket " + bucketName + " already exists.");
            }
        } catch (Exception e) {
            log.error(e.getMessage(), e);
        }
    }
}
